package com.pokermind.operator;

import com.pokermind.model.dto.PlayerBehaviorResponse;
import com.pokermind.model.po.PokerUser;
import com.pokermind.model.po.PokerHand;
import com.pokermind.model.po.PokerHandAction;
import com.pokermind.repository.dao.PokerUserDao;
import com.pokermind.repository.dao.PokerHandDao;
import com.pokermind.repository.dao.PokerHandActionDao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 玩家行为数据操作类
 * 简化的德州扑克行为分析，用于大模型决策
 * 
 * @author PokerMind Team
 */
@Service
public class PlayerBehaviorOperator {
    
    private static final Logger logger = LoggerFactory.getLogger(PlayerBehaviorOperator.class);
    
    @Autowired
    private PokerUserDao pokerUserDao;
    
    @Autowired
    private PokerHandDao pokerHandDao;
    
    @Autowired
    private PokerHandActionDao pokerHandActionDao;
    
    /**
     * 获取玩家行为数据
     */
    public PlayerBehaviorResponse getPlayerBehavior(Long userId) {
        logger.info("获取玩家行为数据: userId={}", userId);
        
        PokerUser user = pokerUserDao.findById(userId).orElse(null);
        if (user == null) {
            throw new IllegalArgumentException("玩家不存在: " + userId);
        }
        
        // 检查是否需要更新行为数据
        if (needsBehaviorUpdate(user)) {
            updatePlayerBehavior(userId);
            // 重新获取更新后的用户数据
            user = pokerUserDao.findById(userId).orElse(null);
        }
        
        return buildBehaviorResponse(user);
    }
    
    /**
     * 更新玩家行为数据
     */
    public void updatePlayerBehavior(Long userId) {
        logger.info("更新玩家行为数据: userId={}", userId);
        
        PokerUser user = pokerUserDao.findById(userId).orElse(null);
        if (user == null) {
            logger.warn("用户不存在，跳过行为数据更新: userId={}", userId);
            return;
        }
        
        try {
            // 获取用户手牌数据 (获取最近1000手)
            List<PokerHand> hands = pokerHandDao.findByUserId(userId, 1000);
            
            if (hands.isEmpty()) {
                logger.info("用户无手牌数据，设置默认行为: userId={}", userId);
                setDefaultBehavior(user);
                pokerUserDao.update(user);
                return;
            }
            
            // 计算行为数据
            BehaviorData behaviorData = calculateBehaviorData(userId, hands);
            
            // 更新用户行为数据
            user.updateBehaviorData(
                behaviorData.vpipRate,
                behaviorData.aggressionLevel,
                behaviorData.winRate,
                behaviorData.playingStyle,
                behaviorData.recentForm
            );
            
            pokerUserDao.update(user);
            
            logger.info("行为数据更新完成: userId={}, hands={}, vpip={}, style={}", 
                       userId, hands.size(), behaviorData.vpipRate, behaviorData.playingStyle);
            
        } catch (Exception e) {
            logger.error("行为数据计算失败: userId={}", userId, e);
            throw new RuntimeException("Failed to update player behavior", e);
        }
    }
    
    /**
     * 检查是否需要更新行为数据
     */
    private boolean needsBehaviorUpdate(PokerUser user) {
        // 如果从未更新过，需要更新
        if (user.getUpdateTime() == null) {
            return true;
        }
        
        // 如果超过6小时未更新，需要更新
        long sixHoursAgo = System.currentTimeMillis() - (6 * 60 * 60 * 1000L);
        return user.getUpdateTime() < sixHoursAgo;
    }
    
    /**
     * 计算行为数据
     */
    private BehaviorData calculateBehaviorData(Long userId, List<PokerHand> hands) {
        BehaviorData data = new BehaviorData();
        
        int totalHands = hands.size();
        int vpipHands = 0;  // 自愿投入底池的手数
        int winHands = 0;   // 获胜手数
        int aggressiveActions = 0;  // 进攻性动作
        int totalActions = 0;       // 总动作数
        
        // 最近30手的表现（用于判断状态）
        int recentHands = Math.min(30, totalHands);
        int recentWins = 0;
        BigDecimal recentProfit = BigDecimal.ZERO;
        
        for (int i = 0; i < hands.size(); i++) {
            PokerHand hand = hands.get(i);
            
            // 计算胜率
            if (hand.getHeroNetResult() != null && hand.getHeroNetResult().compareTo(BigDecimal.ZERO) > 0) {
                winHands++;
                
                // 最近手数的胜率（用于判断最近状态）
                if (i >= totalHands - recentHands) {
                    recentWins++;
                    recentProfit = recentProfit.add(hand.getHeroNetResult());
                }
            }
            
            // 分析该手牌的动作
            List<PokerHandAction> actions = pokerHandActionDao.findByHandId(hand.getId());
            boolean voluntaryPutMoney = false;
            
            for (PokerHandAction action : actions) {
                if (!isUserAction(action, userId)) {
                    continue;
                }
                
                totalActions++;
                String actionType = action.getActionType();
                
                // 自愿投入底池（使用常量）
                if (PokerHandAction.ACTION_CALL.equals(actionType) || 
                    PokerHandAction.ACTION_RAISE.equals(actionType) || 
                    PokerHandAction.ACTION_BET.equals(actionType) || 
                    PokerHandAction.ACTION_ALLIN.equals(actionType)) {
                    voluntaryPutMoney = true;
                }
                
                // 进攻性动作（使用常量）
                if (PokerHandAction.ACTION_RAISE.equals(actionType) || 
                    PokerHandAction.ACTION_BET.equals(actionType) || 
                    PokerHandAction.ACTION_ALLIN.equals(actionType)) {
                    aggressiveActions++;
                }
            }
            
            if (voluntaryPutMoney) {
                vpipHands++;
            }
        }
        
        // 计算VPIP（入池率）
        data.vpipRate = totalHands > 0 ? 
            BigDecimal.valueOf(vpipHands * 100.0 / totalHands).setScale(1, RoundingMode.HALF_UP) :
            BigDecimal.ZERO;
        
        // 计算胜率
        data.winRate = totalHands > 0 ?
            BigDecimal.valueOf(winHands * 100.0 / totalHands).setScale(1, RoundingMode.HALF_UP) :
            BigDecimal.ZERO;
        
        // 计算进攻性水平
        double aggressionRate = totalActions > 0 ? (double) aggressiveActions / totalActions : 0.0;
        if (aggressionRate >= 0.4) {
            data.aggressionLevel = "高";
        } else if (aggressionRate >= 0.2) {
            data.aggressionLevel = "中";
        } else {
            data.aggressionLevel = "低";
        }
        
        // 计算玩牌风格
        double vpipValue = data.vpipRate.doubleValue();
        boolean isTight = vpipValue <= 25.0;  // VPIP <= 25% 为紧
        boolean isAggressive = "高".equals(data.aggressionLevel);
        
        if (isTight && isAggressive) {
            data.playingStyle = "紧凶";
        } else if (!isTight && isAggressive) {
            data.playingStyle = "松凶";
        } else if (isTight && !isAggressive) {
            data.playingStyle = "紧弱";
        } else {
            data.playingStyle = "松弱";
        }
        
        // 判断最近状态
        if (recentHands >= 10) {
            double recentWinRate = (double) recentWins / recentHands;
            if (recentWinRate >= 0.7 || (recentProfit.compareTo(BigDecimal.ZERO) > 0 && recentWinRate >= 0.6)) {
                data.recentForm = "上头";  // 最近状态很好
            } else if (recentWinRate <= 0.3 || recentProfit.compareTo(BigDecimal.valueOf(-100)) < 0) {
                data.recentForm = "下头";  // 最近状态不好
            } else {
                data.recentForm = "正常";
            }
        } else {
            data.recentForm = "正常";
        }
        
        return data;
    }
    
    /**
     * 设置默认行为数据
     */
    private void setDefaultBehavior(PokerUser user) {
        user.setVpipRate(BigDecimal.ZERO);
        user.setAggressionLevel("低");
        user.setWinRate(BigDecimal.ZERO);
        user.setPlayingStyle("新手");
        user.setRecentForm("正常");
        user.setUpdateTime(System.currentTimeMillis());
    }
    
    /**
     * 构建行为响应
     */
    private PlayerBehaviorResponse buildBehaviorResponse(PokerUser user) {
        PlayerBehaviorResponse response = new PlayerBehaviorResponse(user.getId(), user.getPlayerId());
        
        response.setTotalHands(user.getTotalHands());
        response.setVpipRate(user.getVpipRate());
        response.setAggressionLevel(user.getAggressionLevel());
        response.setWinRate(user.getWinRate());
        response.setPlayingStyle(user.getPlayingStyle());
        response.setRecentForm(user.getRecentForm());
        response.setDataReliable(user.isBehaviorDataReliable());
        // 暂时使用updateTime转换为LocalDateTime
        response.setLastUpdated(user.getUpdateTime() != null ? 
            java.time.Instant.ofEpochMilli(user.getUpdateTime()).atZone(java.time.ZoneId.systemDefault()).toLocalDateTime() : 
            null);
        
        return response;
    }
    
    /**
     * 内部行为数据类
     */
    private static class BehaviorData {
        BigDecimal vpipRate;
        String aggressionLevel;
        BigDecimal winRate;
        String playingStyle;
        String recentForm;
    }

    // ========== 辅助方法 ==========
    
    /**
     * 检查是否是用户的动作 - 使用高性能的userId字段
     * 
     * 架构优化：
     * - 使用Long类型的userId进行数字比较，性能比字符串快约10倍
     * - 避免了复杂的字符串匹配和转换逻辑  
     * - 支持大规模用户行为分析的高效查询
     */
    private boolean isUserAction(PokerHandAction action, Long userId) {
        return action.getUserId() != null && action.getUserId().equals(userId);
    }
}
